function waveInit()
{
//  log('waveInit '+wave+' '+wave.isInWaveContainer());
//  if (wave && wave.isInWaveContainer())
  if(wave)
  {
    //log('set callbacks');
    wave.setStateCallback(stateUpdated);
    wave.setParticipantCallback(participantsUpdated);
  }                    
}

function log(text)
{
  $("#log").append("<p>"+text+"</p>");
}

function stateUpdated()
{
  log('updated');
  var size=19;
  var colors=['black', 'white'];
  
  var state=wave.getState();
  
  var toplay=state.get('toplay', '0');
  var players=JSON.parse(state.get('players', '[]'));
  if(players.length==0)
  {
    $("#playersContainer").html("<b>Players</b><br/>No one");
  }
  else
  {
    $("#playersContainer").html('<b>Players</b><br/><ul id="playerList"></ul>');
    
    for(var x=0; x<players.length; x++)
    {
      var player=players[x].split('@')[0];
      if(x==toplay)
      {
        $("#playerList").append('<li> <div style="border: solid 1px black; width: 10px; height: 10px; background-color: '+colors[x]+';" class="swatch"/> <b>'+player+'</b></li>');
      }
      else
      {
        $("#playerList").append('<li> <div style="border: solid 1px black; width: 10px; height: 10px; background-color: '+colors[x]+';" class="swatch"/> '+player+'</li>');
      }
    }
  }
      
  for(var y=0; y<size; y++)
  {
    for(var x=0; x<size; x++)
    {
      cellId='cell_'+x+'_'+y;
      cellState=parseInt(state.get(cellId, '-1'), 10);
      if(cellState!=-1)
      {
        //log('non-gray: '+cellId+' '+cellState);
        if(cellState==0)
        {
          $('#'+cellId).addClass('black');
        }
        else
        {
          $('#'+cellId).addClass('white');
        }
      }
    }
  }
}

function participantsUpdate()
{
}

function checkLegal(state, x, y, playerId)
{
  var opposite = (playerId==0) ? 1 : 0;
  return !((checkCell(state, x+1, y+1, playerId) && checkCell(state, x+1, y, opposite) && checkCell(state, x, y+1, opposite)) ||
         (checkCell(state, x+1, y-1, playerId) && checkCell(state, x+1, y, opposite) && checkCell(state, x, y-1, opposite)) ||
         (checkCell(state, x-1, y+1, playerId) && checkCell(state, x-1, y, opposite) && checkCell(state, x, y+1, opposite)) ||
         (checkCell(state, x-1, y-1, playerId) && checkCell(state, x-1, y, opposite) && checkCell(state, x, y-1, opposite)))
}

function checkCell(state, x, y, color)
{
  if(x<0 || y<0)
  {
    return false;
  }
  else if(x>18 || y>18)
  {
    return false;
  }
  else
  {
    return parseInt(state.get('cell_'+x+'_'+y, '-1'), 10)==color;
  }
}

function place()
{
  var l=this.id.split('_');
  var x=parseInt(l[1], 10);
  var y=parseInt(l[2], 10);

  log('place: '+l);
  
  var viewer=wave.getViewer().getId();
  var state=wave.getState();
  
  var delta={};
  var dirty=false;

  var toplay=parseInt(state.get('toplay', '0'), 10);
  var players=JSON.parse(state.get('players', '[]'));
  var playerId=players.indexOf(viewer);
  if(playerId==-1) // Not currently playing
  {
    if(players.length<2) // Start playing
    {
      players.push(viewer)
      playerId=players.indexOf(viewer);
      delta['players']=JSON.stringify(players);
    }
    else // Full up
    {
      log('full up');
      return;
    }
  }

  if(playerId!=toplay) // Playing out of turn
  {
    log('out of turn '+playerId+' '+toplay);
    return;
  }
  
  var oldCell=parseInt(state.get(this.id, '-1'));
  if(oldCell==-1) // Cell is empty, valid move
  {
    if(checkLegal(state, x, y, playerId))
    {  
      delta[this.id]=playerId;
      if(toplay==0)
      {
        delta['toplay']=1
      }
      else
      {
        delta['toplay']=0
      }
      dirty=true;    
    }
    else
    {
      log('illegal move');
      return;
    }
  }
  else // Cell is not empty, invalid move
  {
    log('invalid move');
    return;
  }

  if(dirty)
  {
    state.submitDelta(delta);
    //log('changed '+delta);
  }  
}

function init()
{
  //log('init');
  createGoBoard(19);
  $(".boardCell").click(place);
  waveInit();
}

$(document).ready(init());

